# @Version        : 1.0
# @Update Time    : 2025/10/15 00:00
# @File           : enums.py
# @IDE            : PyCharm
# @Desc           : 认证相关枚举类
from enum import Enum, StrEnum, unique

__all__ = [
    "ReplacedRange",
    "LogoutMode",
    "LogoutRange",
    "TokenStyle",
    "ErrorEnum",
    "LoginTypeEnum",
    "DeviceTypeEnum",
    "OverflowLogoutModeEnum",
    "ErrorCodeEnum",
    "TokenErrorType",
    "LoginIdMark",
]

from typing import Optional


@unique
class TokenErrorType(Enum):
    """Token错误类型枚举"""

    NOT_TOKEN = {"error_type": "not_token", "message": "未能读取到有效Token"}
    INVALID_TOKEN = {"error_type": "invalid_token", "message": "Token无效"}
    TOKEN_TIMEOUT = {"error_type": "token_timeout", "message": "Token已过期"}
    BE_REPLACED = {"error_type": "be_replaced", "message": "Token已被顶下线"}
    KICK_OUT = {"error_type": "kick_out", "message": "Token已被踢下线"}
    TOKEN_FREEZE = {"error_type": "token_freeze", "message": "Token已被冻结"}
    NO_PREFIX = {"error_type": "no_prefix", "message": "Token缺少前缀"}

    @property
    def error_type(self) -> str:
        """获取错误类型"""
        return self.value.get("error_type", "unknown")

    @property
    def message(self) -> str:
        """获取错误消息"""
        return self.value.get("message", "未知的Token错误")

    @classmethod
    def get_by_error_type(cls, error_type: str) -> Optional["TokenErrorType"]:
        """
        根据错误类型字符串获取对应的枚举实例

        Args:
            error_type: 错误类型字符串

        Returns:
            对应的枚举实例，如果找不到则返回None
        """
        for item in cls:
            if item.error_type == error_type:
                return item
        return None


class ErrorEnum(Enum):
    NOT_TOKEN = {"code": "-1", "message": "未能读取到有效 token"}
    INVALID_TOKEN = {"code": "-2", "message": "token 无效"}
    TOKEN_TIMEOUT = {"code": "-3", "message": "token 已过期"}
    BE_REPLACED = {"code": "-4", "message": "token 已被顶下线"}
    KICK_OUT = {"code": "-5", "message": "token 已被踢下线"}
    TOKEN_FREEZE = {"code": "-6", "message": "token 已被冻结"}
    NO_PREFIX = {"code": "-7", "message": "未按照指定前缀提交 token"}

    @property
    def code(self):
        return self.value["code"]

    @property
    def message(self):
        return self.value["message"]

    @classmethod
    def get_abnormal_list(cls):
        return [item.code for item in cls]


class ErrorCodeEnum(Enum):
    """
    错误枚举类
    定义认证相关的错误码
    """

    # 成功
    SUCCESS = 0

    # 未登录
    NOT_LOGIN = 10001

    # Token无效
    TOKEN_INVALID = 10002

    # Token过期
    TOKEN_EXPIRED = 10003

    # Token不存在
    TOKEN_NOT_FOUND = 10004

    # Token被冻结
    TOKEN_FROZEN = 10005

    # Token活跃时间过期
    TOKEN_ACTIVE_TIMEOUT = 10006

    # 账号不存在
    ACCOUNT_NOT_FOUND = 10101

    # 账号被冻结
    ACCOUNT_FROZEN = 10102

    # 账号被禁用
    ACCOUNT_DISABLED = 10103

    # 密码错误
    PASSWORD_ERROR = 10104

    # 验证码错误
    CAPTCHA_ERROR = 10105

    # 验证码过期
    CAPTCHA_EXPIRED = 10106

    # 登录失败次数过多
    LOGIN_FAILED_TOO_MANY = 10107

    # 无角色
    NO_ROLE = 10201

    # 角色无效
    ROLE_INVALID = 10202

    # 无权限
    NO_PERMISSION = 10301

    # 权限无效
    PERMISSION_INVALID = 10302

    # 参数错误
    PARAMETER_ERROR = 10400

    # 系统错误
    SYSTEM_ERROR = 10500

    # 业务错误
    BUSINESS_ERROR = 10600

    @property
    def code(self) -> int:
        """
        获取错误码
        """
        return self.value

    @property
    def message(self) -> str:
        """
        获取错误消息
        """
        messages = {
            self.SUCCESS: "成功",
            self.NOT_LOGIN: "未登录",
            self.TOKEN_INVALID: "Token无效",
            self.TOKEN_EXPIRED: "Token过期",
            self.TOKEN_NOT_FOUND: "Token不存在",
            self.TOKEN_FROZEN: "Token被冻结",
            self.TOKEN_ACTIVE_TIMEOUT: "Token活跃时间过期",
            self.ACCOUNT_NOT_FOUND: "账号不存在",
            self.ACCOUNT_FROZEN: "账号被冻结",
            self.ACCOUNT_DISABLED: "账号被禁用",
            self.PASSWORD_ERROR: "密码错误",
            self.CAPTCHA_ERROR: "验证码错误",
            self.CAPTCHA_EXPIRED: "验证码过期",
            self.LOGIN_FAILED_TOO_MANY: "登录失败次数过多",
            self.NO_ROLE: "无角色",
            self.ROLE_INVALID: "角色无效",
            self.NO_PERMISSION: "无权限",
            self.PERMISSION_INVALID: "权限无效",
            self.PARAMETER_ERROR: "参数错误",
            self.SYSTEM_ERROR: "系统错误",
            self.BUSINESS_ERROR: "业务错误",
        }
        return messages.get(self, "未知错误")


class LoginTypeEnum(Enum):
    """
    登录类型枚举
    """

    # 用户登录
    USER = "user"

    # 管理员登录
    ADMIN = "admin"

    # 第三方登录
    THIRD_PARTY = "third_party"

    # 临时登录
    TEMP = "temp"


class DeviceTypeEnum(Enum):
    """
    设备类型枚举
    """

    # PC端
    PC = "pc"

    # 移动端
    MOBILE = "mobile"

    # 平板
    TABLET = "tablet"

    # 小程序
    MINI_PROGRAM = "mini_program"

    # 其他
    OTHER = "other"


class OverflowLogoutModeEnum(Enum):
    """
    溢出注销模式枚举
    """

    # 注销最早登录的会话
    OLDEST = "oldest"

    # 注销最新登录的会话
    NEWEST = "newest"


class ReplacedRange(StrEnum):
    """
    顶人下线的范围
    """

    # 当前指定的设备类型端
    CURR_DEVICE_TYPE = "CURR_DEVICE_TYPE"
    # 所有设备类型端
    ALL_DEVICE_TYPE = "ALL_DEVICE_TYPE"


class LogoutMode(StrEnum):
    """
    注销下线方式
    """

    # 注销下线
    LOGOUT = "LOGOUT"
    # 踢人下线
    KICKOUT = "KICKOUT"
    # 顶人下线
    REPLACED = "REPLACED"


class LogoutRange(StrEnum):
    # token 范围：只注销提供的 token 指向的会话
    TOKEN = "TOKEN"
    # 账号范围：注销 token 指向的 loginId 会话
    ACCOUNT = "ACCOUNT"


class TokenStyle(StrEnum):
    """
    Token 风格: （默认可取值：uuid、simple-uuid、random-32、random-64、random-128、tik）
    """

    UUID = "uuid"
    SIMPLE_UUID = "simple-uuid"
    RANDOM_32 = "random-32"
    RANDOM_64 = "random-64"
    RANDOM_128 = "random-128"
    TIK = "tik"


class LoginIdMark(StrEnum):
    """
    login_id 映射中的异常标记值，避免魔法字符串
    """

    TOKEN_TIMEOUT = "TOKEN_TIMEOUT"
    BE_REPLACED = "BE_REPLACED"
    KICK_OUT = "KICK_OUT"
